﻿using AconITF.Common;
using AconITF.Core.Models;
using AconITF.Extension;
using AconITF.Windows;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.Native;
using Microsoft.Win32;
using SciChart.Charting.Model.ChartSeries;
using SciChart.Charting.Model.DataSeries;
using SciChart.Charting.Visuals.RenderableSeries;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AconITF.ViewModels
{
	[POCOViewModel]
	public class MainViewModel
	{
		public MainViewModel()
		{
			AllVars = GlobalData.AllVars;
			testc();
		}

		private async void testc()
		{
			int index = 0;
			Random random = new Random();
			while (true)
			{
				foreach (var item in AllVars.Values)
				{
					item.CurrentValue = random.Next(40);
				}

				await Task.Delay(500);
				foreach (var item in DataSeriesDict)
				{
					item.Value.Append(index, item.Key.CurrentValue);
				}

				index++;
			}
		}

		#region Binding
		/// <summary>
		/// 实时曲线序列
		/// </summary>
		public virtual ObservableCollection<IRenderableSeriesViewModel> RealTimeSeries { get; set; } = new ObservableCollection<IRenderableSeriesViewModel>();

		/// <summary>
		/// 离线曲线序列
		/// </summary>
		public virtual ObservableCollection<IRenderableSeriesViewModel> OfflineSeries { get; set; } = new ObservableCollection<IRenderableSeriesViewModel>();

		/// <summary>
		/// 所有变量的字典
		/// </summary>
		public virtual Dictionary<string, VariableItem> AllVars { get; set; } = new Dictionary<string, VariableItem>();

		/// <summary>
		/// 是否处于回放状态
		/// </summary>
		public virtual bool IsPlayback { get; set; }

		/// <summary>
		/// 图表数据序列字典
		/// </summary>
		private Dictionary<VariableItem, XyDataSeries<int, double>> DataSeriesDict = new Dictionary<VariableItem, XyDataSeries<int, double>>();

		/// <summary>
		/// 离线图表数据序列字典
		/// </summary>
		private Dictionary<VariableItem, XyDataSeries<int, double>> OffDataSeriesDict = new Dictionary<VariableItem, XyDataSeries<int, double>>();

		/// <summary>
		/// 是否正在录制数据
		/// </summary>
		public virtual bool IsRecording { get; set; }
		#endregion

		public void ToggleSignal(VariableItem variable)
		{
			// 实时曲线序列
			if (variable.IsSelected && !DataSeriesDict.ContainsKey(variable))
			{
				DataSeriesDict[variable] = new XyDataSeries<int, double>() { SeriesName = variable.Name, Tag = variable };
				RealTimeSeries.Add(new LineRenderableSeriesViewModel()
				{
					DataSeries = DataSeriesDict[variable],
					Stroke = ChartColor.GetColor(RealTimeSeries.Count)
				});
			}
			else if (!variable.IsSelected && DataSeriesDict.ContainsKey(variable))
			{
				var line = RealTimeSeries.FirstOrDefault(x => x.DataSeries.Tag == variable);
				if (line != null)
				{
					RealTimeSeries.Remove(line);
				}
				DataSeriesDict.Remove(variable);
			}

			// 离线曲线序列
			if (variable.IsSelected && !OffDataSeriesDict.ContainsKey(variable))
			{
				OffDataSeriesDict[variable] = new XyDataSeries<int, double>() { SeriesName = variable.Name, Tag = variable };
				OfflineSeries.Add(new LineRenderableSeriesViewModel()
				{
					DataSeries = OffDataSeriesDict[variable],
					Stroke = ChartColor.GetColor(OfflineSeries.Count)
				});

				int index = 0;
				int singLength = AllVars.Count * 8;
				for (int i = 0; i < offDataBuffer.Length / singLength; i++)
				{
					var value = BitConverter.ToDouble(offDataBuffer, variable.Id * 8 + index * singLength);
					OffDataSeriesDict[variable].Append(i, value);
					index++;
				}
			}
			else if (!variable.IsSelected && OffDataSeriesDict.ContainsKey(variable))
			{
				var line = OfflineSeries.FirstOrDefault(x => x.DataSeries.Tag == variable);
				if (line != null)
				{
					OfflineSeries.Remove(line);
				}
				OffDataSeriesDict.Remove(variable);
			}
		}

		BinaryWriter writer;
		/// <summary>
		/// 开始保存数据
		/// </summary>
		public void StartStopSave()
		{
			if (IsRecording)
			{
				writer.Close();
				IsRecording = false;
			}
			else
			{
				SaveFileDialog sfd = new SaveFileDialog();
				sfd.Filter = "DAT文件|*.dat";
				if (sfd.ShowDialog() != true)
				{
					return;
				}

				writer = new BinaryWriter(File.Open(sfd.FileName, FileMode.Create));
				IsRecording = true;
				WriteData();
			}
		}

		private async void WriteData()
		{
			while (IsRecording)
			{
				List<byte> bytes = new List<byte>();
				foreach (var item in AllVars.Values)
				{
					bytes.AddRange(BitConverter.GetBytes(item.CurrentValue));
				}

				writer.Write(bytes.ToArray());
				await Task.Delay(100);
			}
		}

		byte[] offDataBuffer = new byte[4];
		public void Playback(bool isPlayback)
		{
			if (!isPlayback)
			{
				IsPlayback = false;
				return;
			}

			OpenFileDialog ofd = new OpenFileDialog();
			ofd.Filter = "DAT文件|*.dat";
			if (ofd.ShowDialog() != true)
			{
				return;
			}

			IsPlayback = true;
			offDataBuffer = File.ReadAllBytes(ofd.FileName);
			OfflineSeries.Clear();
			OffDataSeriesDict.Clear();
			foreach (var item in AllVars.Values.Where(x => x.IsSelected))
			{
				OffDataSeriesDict[item] = new XyDataSeries<int, double>() { SeriesName = item.Name, Tag = item };
				OfflineSeries.Add(new LineRenderableSeriesViewModel()
				{
					DataSeries = OffDataSeriesDict[item],
					Stroke = ChartColor.GetColor(OfflineSeries.Count)
				});

				int index = 0;
				int singLength = AllVars.Count * 8;
				for (int i = 0; i < offDataBuffer.Length / singLength; i++)
				{
					var value = BitConverter.ToDouble(offDataBuffer, item.Id * 8 + index * singLength);
					OffDataSeriesDict[item].Append(i, value);
					index++;
				}
			}
		}

		/// <summary>
		/// 显示电源控制窗口
		/// </summary>
		public void ShowPowerControl()
		{
			GlobalData.PowerWinInstance.Show();
		}

		public void ShowLoadControl()
		{
			RackDoorWindow window = new RackDoorWindow();
			window.ShowDialog();
		}
	}
}
